const { ShareStatistics, User } = require('../models')
const logger = require('../utils/logger')

class ShareStatisticsService {
  /**
   * 记录分享行为
   * @param {Object} shareData - 分享数据
   * @returns {Promise<Object>} 记录结果
   */
  static async recordShare(shareData) {
    try {
      const {
        userId,
        inviteCode,
        shareChannel,
        sharePlatform,
        ipAddress,
        userAgent
      } = shareData

      // 查找或创建分享统计记录
      let shareRecord = await ShareStatistics.findOne({
        where: {
          user_id: userId,
          invite_code: inviteCode,
          share_channel: shareChannel,
          share_platform: sharePlatform
        }
      })

      if (shareRecord) {
        // 更新现有记录
        await shareRecord.update({
          updated_at: new Date()
        })
      } else {
        // 创建新记录
        shareRecord = await ShareStatistics.create({
          user_id: userId,
          invite_code: inviteCode,
          share_channel: shareChannel,
          share_platform: sharePlatform,
          ip_address: ipAddress,
          user_agent: userAgent
        })
      }

      logger.info(`记录分享行为: 用户 ${userId}, 渠道 ${shareChannel}, 平台 ${sharePlatform}`)

      return {
        success: true,
        data: shareRecord
      }
    } catch (error) {
      logger.error('记录分享行为失败:', error)
      throw error
    }
  }

  /**
   * 记录邀请链接点击
   * @param {string} inviteCode - 邀请码
   * @param {string} shareChannel - 分享渠道
   * @param {string} sharePlatform - 分享平台
   * @returns {Promise<void>}
   */
  static async recordClick(inviteCode, shareChannel = 'unknown', sharePlatform = 'unknown') {
    try {
      const shareRecord = await ShareStatistics.findOne({
        where: {
          invite_code: inviteCode,
          share_channel: shareChannel,
          share_platform: sharePlatform
        }
      })

      if (shareRecord) {
        await shareRecord.increment('click_count')
        logger.info(`记录邀请链接点击: 邀请码 ${inviteCode}, 渠道 ${shareChannel}`)
      }
    } catch (error) {
      logger.error('记录邀请链接点击失败:', error)
    }
  }

  /**
   * 记录注册转化
   * @param {string} inviteCode - 邀请码
   * @param {string} shareChannel - 分享渠道
   * @param {string} sharePlatform - 分享平台
   * @returns {Promise<void>}
   */
  static async recordRegisterConversion(inviteCode, shareChannel = 'unknown', sharePlatform = 'unknown') {
    try {
      const shareRecord = await ShareStatistics.findOne({
        where: {
          invite_code: inviteCode,
          share_channel: shareChannel,
          share_platform: sharePlatform
        }
      })

      if (shareRecord) {
        await shareRecord.increment('register_count')
        logger.info(`记录注册转化: 邀请码 ${inviteCode}, 渠道 ${shareChannel}`)
      }
    } catch (error) {
      logger.error('记录注册转化失败:', error)
    }
  }

  /**
   * 获取用户分享统计
   * @param {number} userId - 用户ID
   * @returns {Promise<Object>} 分享统计数据
   */
  static async getUserShareStats(userId) {
    try {
      const { Op } = require('sequelize')
      const sequelize = require('../config/database')

      // 获取分享渠道统计
      const channelStats = await ShareStatistics.findAll({
        where: { user_id: userId },
        attributes: [
          'share_channel',
          [sequelize.fn('SUM', sequelize.col('click_count')), 'total_clicks'],
          [sequelize.fn('SUM', sequelize.col('register_count')), 'total_registers'],
          [sequelize.fn('COUNT', sequelize.col('id')), 'share_times']
        ],
        group: ['share_channel'],
        order: [[sequelize.fn('SUM', sequelize.col('click_count')), 'DESC']]
      })

      // 获取平台统计
      const platformStats = await ShareStatistics.findAll({
        where: { user_id: userId },
        attributes: [
          'share_platform',
          [sequelize.fn('SUM', sequelize.col('click_count')), 'total_clicks'],
          [sequelize.fn('SUM', sequelize.col('register_count')), 'total_registers'],
          [sequelize.fn('COUNT', sequelize.col('id')), 'share_times']
        ],
        group: ['share_platform'],
        order: [[sequelize.fn('SUM', sequelize.col('click_count')), 'DESC']]
      })

      // 计算总统计
      const totalStats = await ShareStatistics.findOne({
        where: { user_id: userId },
        attributes: [
          [sequelize.fn('SUM', sequelize.col('click_count')), 'total_clicks'],
          [sequelize.fn('SUM', sequelize.col('register_count')), 'total_registers'],
          [sequelize.fn('COUNT', sequelize.col('id')), 'total_shares']
        ]
      })

      // 计算转化率
      const totalClicks = parseInt(totalStats.getDataValue('total_clicks')) || 0
      const totalRegisters = parseInt(totalStats.getDataValue('total_registers')) || 0
      const conversionRate = totalClicks > 0 ? Math.round((totalRegisters / totalClicks) * 100) : 0

      return {
        channelStats: channelStats.map(stat => ({
          channel: stat.share_channel,
          clicks: parseInt(stat.getDataValue('total_clicks')) || 0,
          registers: parseInt(stat.getDataValue('total_registers')) || 0,
          shareTimes: parseInt(stat.getDataValue('share_times')) || 0,
          conversionRate: stat.getDataValue('total_clicks') > 0 ? 
            Math.round((stat.getDataValue('total_registers') / stat.getDataValue('total_clicks')) * 100) : 0
        })),
        platformStats: platformStats.map(stat => ({
          platform: stat.share_platform,
          clicks: parseInt(stat.getDataValue('total_clicks')) || 0,
          registers: parseInt(stat.getDataValue('total_registers')) || 0,
          shareTimes: parseInt(stat.getDataValue('share_times')) || 0,
          conversionRate: stat.getDataValue('total_clicks') > 0 ? 
            Math.round((stat.getDataValue('total_registers') / stat.getDataValue('total_clicks')) * 100) : 0
        })),
        totalStats: {
          totalClicks,
          totalRegisters,
          totalShares: parseInt(totalStats.getDataValue('total_shares')) || 0,
          conversionRate
        }
      }
    } catch (error) {
      logger.error('获取用户分享统计失败:', error)
      throw error
    }
  }

  /**
   * 获取最佳分享渠道推荐
   * @param {number} userId - 用户ID
   * @returns {Promise<Array>} 推荐渠道列表
   */
  static async getRecommendedChannels(userId) {
    try {
      const stats = await this.getUserShareStats(userId)
      
      // 按转化率和点击量排序推荐渠道
      const recommendations = stats.channelStats
        .filter(channel => channel.clicks > 0)
        .sort((a, b) => {
          // 优先按转化率排序，转化率相同则按点击量排序
          if (b.conversionRate !== a.conversionRate) {
            return b.conversionRate - a.conversionRate
          }
          return b.clicks - a.clicks
        })
        .slice(0, 3) // 取前3个推荐渠道

      // 如果没有历史数据，返回默认推荐
      if (recommendations.length === 0) {
        return [
          { channel: 'wechat', reason: '微信好友转化率通常较高' },
          { channel: 'moments', reason: '朋友圈覆盖面广' },
          { channel: 'qrcode', reason: '二维码分享便捷' }
        ]
      }

      return recommendations.map(channel => ({
        channel: channel.channel,
        conversionRate: channel.conversionRate,
        clicks: channel.clicks,
        registers: channel.registers,
        reason: this.getChannelRecommendReason(channel)
      }))
    } catch (error) {
      logger.error('获取推荐分享渠道失败:', error)
      throw error
    }
  }

  /**
   * 获取渠道推荐理由
   * @param {Object} channelData - 渠道数据
   * @returns {string} 推荐理由
   */
  static getChannelRecommendReason(channelData) {
    const { channel, conversionRate, clicks } = channelData

    if (conversionRate >= 20) {
      return `${this.getChannelName(channel)}转化率高达${conversionRate}%，效果优秀`
    } else if (conversionRate >= 10) {
      return `${this.getChannelName(channel)}转化率${conversionRate}%，效果良好`
    } else if (clicks >= 50) {
      return `${this.getChannelName(channel)}点击量较高，覆盖面广`
    } else {
      return `${this.getChannelName(channel)}是常用分享渠道`
    }
  }

  /**
   * 获取渠道中文名称
   * @param {string} channel - 渠道代码
   * @returns {string} 中文名称
   */
  static getChannelName(channel) {
    const channelNames = {
      wechat: '微信好友',
      moments: '朋友圈',
      qq: 'QQ好友',
      qzone: 'QQ空间',
      weibo: '微博',
      copy: '复制链接',
      qrcode: '二维码'
    }
    return channelNames[channel] || channel
  }

  /**
   * 获取全平台分享效果排行
   * @param {Object} options - 查询选项
   * @returns {Promise<Array>} 排行数据
   */
  static async getShareEffectivenessRanking(options = {}) {
    try {
      const {
        period = 'all', // all, month, week
        limit = 20
      } = options

      const { Op } = require('sequelize')
      const sequelize = require('../config/database')

      let whereClause = {}
      
      // 时间筛选
      if (period === 'month') {
        const startOfMonth = new Date()
        startOfMonth.setDate(1)
        startOfMonth.setHours(0, 0, 0, 0)
        whereClause.created_at = { [Op.gte]: startOfMonth }
      } else if (period === 'week') {
        const startOfWeek = new Date()
        startOfWeek.setDate(startOfWeek.getDate() - startOfWeek.getDay())
        startOfWeek.setHours(0, 0, 0, 0)
        whereClause.created_at = { [Op.gte]: startOfWeek }
      }

      const rankings = await ShareStatistics.findAll({
        where: whereClause,
        attributes: [
          'share_channel',
          [sequelize.fn('SUM', sequelize.col('click_count')), 'total_clicks'],
          [sequelize.fn('SUM', sequelize.col('register_count')), 'total_registers'],
          [sequelize.fn('COUNT', sequelize.col('id')), 'total_shares']
        ],
        group: ['share_channel'],
        order: [[sequelize.fn('SUM', sequelize.col('register_count')), 'DESC']],
        limit
      })

      return rankings.map((item, index) => {
        const totalClicks = parseInt(item.getDataValue('total_clicks')) || 0
        const totalRegisters = parseInt(item.getDataValue('total_registers')) || 0
        const conversionRate = totalClicks > 0 ? Math.round((totalRegisters / totalClicks) * 100) : 0

        return {
          rank: index + 1,
          channel: item.share_channel,
          channelName: this.getChannelName(item.share_channel),
          totalClicks,
          totalRegisters,
          totalShares: parseInt(item.getDataValue('total_shares')) || 0,
          conversionRate
        }
      })
    } catch (error) {
      logger.error('获取分享效果排行失败:', error)
      throw error
    }
  }
}

module.exports = ShareStatisticsService